from typing import List, Any

from PySide6.QtCore import Qt
from PySide6.QtGui import QColor
from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QFrame, QLabel
from qfluentwidgets import (
    ScrollArea,
    ToolTipFilter,
    toggleTheme,
    ToolButton,
    FluentIcon,
    PushButton,
    CaptionLabel,
    TitleLabel,
    StrongBodyLabel,
    BodyLabel,
)

from app.common.style_sheet import StyleSheet
from app.utils.log_rec import logger


class ToolBar(QWidget):
    """Tool bar"""

    def __init__(self, title, subtitle, parent=None):
        super().__init__(parent=parent)
        self.titleLabel = TitleLabel(title, self)
        self.subtitleLabel = CaptionLabel(subtitle, self)
        self.themeButton = ToolButton(FluentIcon.CONSTRACT, self)

        self.vBoxLayout = QVBoxLayout(self)
        self.buttonLayout = QHBoxLayout()

        self.__initW_dget()

    def __initW_dget(self):
        self.setFixedHeight(138)
        self.vBoxLayout.setSpacing(0)
        self.vBoxLayout.setContentsMargins(36, 22, 36, 12)
        self.vBoxLayout.addWidget(self.titleLabel)
        self.vBoxLayout.addSpacing(4)
        self.vBoxLayout.addWidget(self.subtitleLabel)
        self.vBoxLayout.addSpacing(4)
        self.vBoxLayout.addLayout(self.buttonLayout, 1)
        self.vBoxLayout.setAlignment(Qt.AlignmentFlag.AlignTop)

        self.buttonLayout.setSpacing(4)
        self.buttonLayout.setContentsMargins(0, 0, 0, 0)
        self.buttonLayout.addStretch(1)
        self.buttonLayout.addWidget(self.themeButton, 0, Qt.AlignmentFlag.AlignRight)
        self.buttonLayout.setAlignment(
            Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignLeft
        )

        self.themeButton.installEventFilter(ToolTipFilter(self.themeButton))
        self.themeButton.setToolTip(self.tr("Toggle theme"))
        self.themeButton.clicked.connect(lambda: toggleTheme(True))

        self.subtitleLabel.setTextColor(QColor(96, 96, 96), QColor(216, 216, 216))


class CardWithButtonAndLabel(QWidget):

    def __init__(
        self,
        title,
        widget: QWidget,
        stretch=0,
        parent=None,
    ):
        super().__init__(parent=parent)
        self.widget = widget
        self.stretch = stretch
        self.title = title

        self.titleLabel = StrongBodyLabel(title, self)
        self.card = QFrame(self)

        self.vBoxLayout = QVBoxLayout(self)
        self.cardLayout = QVBoxLayout(self.card)
        self.topLayout = QHBoxLayout()
        self.__init_widget()

    def __init_widget(self):
        self.card.setObjectName(self.title)
        self.__init_layout()

    def __init_layout(self):
        self.vBoxLayout.setSizeConstraint(QVBoxLayout.SizeConstraint.SetMinimumSize)
        self.cardLayout.setSizeConstraint(QVBoxLayout.SizeConstraint.SetMinimumSize)
        self.topLayout.setSizeConstraint(QHBoxLayout.SizeConstraint.SetMinimumSize)

        self.vBoxLayout.setSpacing(12)
        self.vBoxLayout.setContentsMargins(0, 0, 0, 0)
        self.topLayout.setContentsMargins(12, 12, 12, 12)
        self.cardLayout.setContentsMargins(0, 0, 0, 0)

        self.vBoxLayout.addWidget(self.titleLabel, 0, Qt.AlignmentFlag.AlignTop)
        self.vBoxLayout.addWidget(self.card, 0, Qt.AlignmentFlag.AlignTop)
        self.vBoxLayout.setAlignment(Qt.AlignmentFlag.AlignTop)

        self.cardLayout.setSpacing(0)
        self.cardLayout.setAlignment(Qt.AlignmentFlag.AlignTop)
        self.cardLayout.addLayout(self.topLayout, 0)

        self.widget.setParent(self.card)
        self.topLayout.addWidget(self.widget)
        if self.stretch == 0:
            self.topLayout.addStretch(1)

        self.widget.show()

    def add_label(self, msg: dict):
        """
        将dict中的value转为label展示
        :param msg:
        :return:
        """
        logger.debug(msg)
        self.widget.setEnabled(False)
        # 先清理已有的label
        ls_label = self.topLayout.count()  # 获取topLayout中的对象个数
        for label in reversed(range(ls_label)):
            item = self.topLayout.itemAt(label)
            widget = item.widget()
            if widget and isinstance(widget, QLabel):
                logger.debug(f"delete {widget}")
                self.topLayout.removeWidget(widget)
                widget.deleteLater()

        # 重新添加label
        for k, v in msg.items():
            logger.debug(f"add label: {k}: {v}")
            __label_k = BodyLabel(self.tr(f"{k}："))
            __label_k.setObjectName(k)
            __label_v = BodyLabel(v)
            __label_v.setObjectName(v)
            self.topLayout.addWidget(__label_k)
            self.topLayout.addWidget(__label_v)

        self.widget.setEnabled(True)


class InterfacesView(ScrollArea):

    def __init__(self, title: str, subtitle: str, parent=None):
        super().__init__(parent=parent)
        self.view = QWidget(self)
        self.toolBar = ToolBar(title, subtitle, self)
        self.vBoxLayout = QVBoxLayout(self.view)

        self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.setViewportMargins(0, self.toolBar.height(), 0, 0)
        self.setWidget(self.view)
        self.setWidgetResizable(True)

        self.vBoxLayout.setSpacing(30)
        self.vBoxLayout.setAlignment(Qt.AlignmentFlag.AlignTop)
        self.vBoxLayout.setContentsMargins(36, 20, 36, 36)

        self.view.setObjectName("view")
        StyleSheet.INTERFACE.apply(self)

    def add_card(self, title, widget: PushButton | List[Any], stretch=0):
        match widget:
            case widget if isinstance(widget, PushButton):
                logger.debug(f"create card:  {title}, {widget}")
                self.card = CardWithButtonAndLabel(
                    title, widget, stretch, parent=self.view
                )
                self.vBoxLayout.addWidget(
                    self.card, stretch=0, alignment=Qt.AlignmentFlag.AlignTop
                )
                return self.card
            case widget if isinstance(widget, List):
                __card = []
                for wi in widget:
                    logger.debug(f"create card:  {title}, {wi}")
                    self.card = CardWithButtonAndLabel(
                        title, wi, stretch, parent=self.view
                    )
                    self.vBoxLayout.addWidget(
                        self.card, stretch=0, alignment=Qt.AlignmentFlag.AlignTop
                    )
                    __card.append(self.card)
                return __card

    def scroll_to_card(self, index: int):
        """scroll to example card"""
        w = self.vBoxLayout.itemAt(index).widget()
        self.verticalScrollBar().setValue(w.y())

    def add_label_to_card(self, msg: dict):
        self.card.add_label(msg)

    def resizeEvent(self, e):
        super().resizeEvent(e)
        self.toolBar.resize(self.width(), self.toolBar.height())
